据我所知，您需要将“ y”传递给ssh-keygen的唯一原因是您的命令是否正在替换现有文件。我认为这不是从配置管理工具执行操作的好方法。
您应该调整任务以使其成为幂等。具体来说，如果您在creates: filename命令中添加，则仅在新键不存在时才创建新键，而不是在每次运行该剧本时都将其替换。
---
- hosts: all
  become: true
  gather_facts: false
tasks:
  - name: Generate /etc/ssh/ RSA host key
    command : ssh-keygen -q -t rsa -f /etc/ssh/ssh_host_rsa_key -C "" -N ""
    args:
      creates: /etc/ssh/ssh_host_rsa_key
- name: Generate /etc/ssh/ DSA host key
    command : ssh-keygen -q -t dsa -f /etc/ssh/ssh_host_dsa_key -C "" -N ""
    args:
      creates: /etc/ssh/ssh_host_dsa_key
- name: Generate /etc/ssh/ ECDSA host key
    command : ssh-keygen -q -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -C "" -N ""
    args:
      creates: /etc/ssh/ssh_host_ecdsa_key
如果由于某种原因您想替换这些键，例如，如果它们太旧，或者您可能想要添加其他任务以将其删除。这是一个简单的删除
- file:
    state: absent:
    path: "{{item}}"
  loop:
  - /etc/ssh/ssh_host_rsa_key
  - /etc/ssh/ssh_host_dsa_key
  - /etc/ssh/ssh_host_ecdsa_key
如果要删除某个时间之前生成的文件，则可以使用stat模块检索有关此文件的详细信息，并设置when条件以有选择地删除它们（如果它们早于某个日期或某个日期）。
分享改善这个答案跟随
19年1月3日于18:54编辑
18年5月3日在17:56 回答

Zoredache
12万3232金徽章245245银章391个391青铜徽章
• 很好的例子，感谢您对保持幂等的想法。对于我的用例，我正在调配克隆的虚拟机，因此总会有要覆盖的密钥。我有点需要核选项才能删除和更换。 –  服务器故障 '18年5月3日在18:04
• 如果您始终希望将其删除，那么我可能会采用将file: state:absent ...内容填充到ssh-keygen的方法。尽管可能没有太大区别。 –  Zoredache '18年 5月3日在19:45
• 喔好吧。这更有意义。我absent几天前都不知道。有效地，这将在重新生成密钥之前删除文件。这是一种更加清晰的方法。谢谢。 –  服务器故障 '18年5月3日在20:09 
添加评论
6
ansible command模块 不会通过shell传递命令。这意味着您不能使用外壳运算符（例如管道），这就是为什么在输出中看到管道符号的原因。就ansible而言，它已将echo其余所有行作为的参数执行了该命令echo。
如果需要外壳程序处理命令行，请使用shell代替command。
而且，应该有一种更好的方法来重新生成ssh主机密钥，但是我现在找不到一个...
分享改善这个答案跟随
18年4月30日在19:19 回答
迈克尔·汉普顿
195k3030金徽章376376银章734个734青铜徽章
• 感谢您提供的Shell vs.命令提示（现在可以正常运行），我不知道-还是很新的Ansible –  服务器故障 18年4月30日，19：24 
• 关于最后一条语句（至少在CentOS / RHEL上），如果您删除了旧密钥并重新启动守护程序主机密钥，则会为您重新生成。无论如何，您都需要重新启动服务，因此这看起来似乎更好。 –  亚伦·科普利 18年4月30日在19:25
• @AaronCopley我比发行服务更多地是指Ansible角色。我知道大多数主要发行版都具有systemd服务，该服务生成ssh主机密钥。不幸的是，该服务具有特定于发行版的细微差别（CentOS和Fedora之间甚至有所不同）。角色是封装所有内容的一种好方法，但是我找不到一个有用的东西。 –  迈克尔·汉普顿 '18 Apr 30'19:27
• 不用担心，只是以为我会提到它。（您可能知道，但OP可能没有。） –  Aaron Copley 18年4月30日在19:31 
• @AaronCopley-顺便说一句，这就是我最终要做的。在echo ...第二次运行后，该位不起作用（我正在测试/tmp/第一次没有键的情况下）。正如您提到的，我首先采取了删除主机密钥的方法，并生成了新的主机密钥。至于自动重新生成密钥，这取决于您的分布，对吗？并非所有Linux发行版都使用systemd。 –  服务器故障 '18 Apr 30，19:40 
再显示4条评论
2
使用特殊模块执行此任务：
- name: Generate an OpenSSH keypair with the default values (4096 bits, rsa)
  openssh_keypair:
    path: /home/youruser/.ssh/id_rsa
    owner: youruser
    group: youruser
- name: Fix owner of the generated pub key
  file:
    path: /home/youruser/.ssh/id_rsa.pub
    owner: youruser
    group: youruser
分享改善这个答案跟随
19年8月28日在14:47 回答

乔尔吉
12122枚青铜徽章
• 这些不是ssh主机密钥 –  KumZ 2月24日在15:05
添加评论
1个
抱歉，但是我无法在任务中使用“创建”。我得到了以下错误：
ERROR! 'creates' is not a valid attribute for a Task
因此，我使用以下任务：
- name: remove existing ssh_host keys
  file: path={{ item }} state=absent
  with_items:
    - "/etc/ssh/ssh_host_rsa_key"
    - "/etc/ssh/ssh_host_dsa_key"
    - "/etc/ssh/ssh_host_ecdsa_key"
- name: Generate /etc/ssh/ RSA host key
  command : ssh-keygen -q -t rsa -f /etc/ssh/ssh_host_rsa_key -C "" -N ""
- name: Generate /etc/ssh/ DSA host key
  command : ssh-keygen -q -t dsa -f /etc/ssh/ssh_host_dsa_key -C "" -N ""
- name: Generate /etc/ssh/ ECDSA host key
  command : ssh-keygen -q -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -C "" -N ""
分享改善这个答案跟随
18年7月10日在15:39编辑
18年7月10日在15:33 回答
马克西·瑞格斯
12133枚青铜徽章
• 2
使用当前版本的Ansible。 –  迈克尔·汉普顿'18 Jul 10'18:40
• 没错，我的Ansible版本有点旧：2.0.0.2 ...（在Ubuntu 16.04上）。我必须改变！ – MaxiReglisse 18年  7月11日在6:22
添加评论
1个
@Zoredache的答案正确，但对于Ansible的最新版本却失败（@MaxiReglisse指出）。请使用以下代码：
---
- hosts: all
  become: true
  gather_facts: false
tasks:
  - name: Generate /etc/ssh/ RSA host key
    command : ssh-keygen -q -t rsa -f /etc/ssh/ssh_host_rsa_key -C "" -N ""
    args:
      creates: /etc/ssh/ssh_host_rsa_key
分享改善这个答案跟随
18年11月14日于10:36编辑
鲁比恩
64.6千1212金徽章106个106银徽章175个175青铜徽章
18年11月14日在9:30 回答

大卫·韦伯
11133枚青铜徽章
添加评论
1个
另一种选择是使用用户模块。积极的一面是您将获得幂等的任务。这是一个示例如何在本地主机上生成ssh密钥的示例：
- name: Generate ssh keys
  local_action:
    module: "user"
    name: "{{ lookup('env','USER') }}"
    generate_ssh_key: true
    ssh_key_type: "{{ item.0 }}"
    ssh_key_bits: "{{ item.1 }}"
    ssh_key_file: "{{ playbook_dir }}/{{ item.0 }}_{{ item.1 }}_key"
  with_together:
  - [ 'rsa', 'dsa' ]
  - [ 2048, 1024 ]
  loop_control:
    label: "{{ item.0 }}_{{ item.1 }}_key"
- name: Copy generated ssh keys to remote machine
  copy:
    src: "{{ playbook_dir }}/{{ item.0 }}_{{ item.1 }}_key"
    dest: "/etc/ssh/ssh_host_{{ item.0 }}_key{{ item.1 }}"
  with_nested:
  - [ 'rsa', 'dsa' ]
  - [ '', '.pub' ]
  notify:
  - Restart sshd
  loop_control:
    label: "/etc/ssh/ssh_host_{{ item.0 }}_key{{ item.1 }}"
分享改善这个答案跟随
19年2月15日于9:08编辑
19年2月15日在8:12 回答
地球英雄
1122枚青铜徽章
• 1个
这不是用户密钥，不是主机密钥吗？-MadHatter 19 年  2月15日在8:17
• 您也可以将其用于主机密钥，因为实际上这是同一回事。只是如果您以强制模式使用SELinux，别忘了还原selinux上下文 –  HeroFromEarth 19 Feb 15 '18 ：34
• 从文档中对我来说还不清楚。如果您要重写答案，以便明确显示正在创建的主机密钥，那么我将删除我的下注。 – MadHatter 19年  2月15日在 8:51
• 好吧，也许还不清楚。我添加了另一个任务来解释如何在远程计算机上复制这些密钥。当然，这只是我的情况（我在群集的几台计算机上需要相同的密钥，因此我需要在本地主机上生成它们），而且我很确定您可以使用“用户”模块为ssh服务器上的密钥生成密钥远程计算机（请查看“ ssh_key_file”） – HeroFromEarth， 19年  2月15日，9：12
• 我仍然不确定是不是骇客行为（至少是因为它使一个用户拥有主机私钥的副本！），但至少现在它可以按要求回答问题了，所以我删除了我的下注。 – MadHatter 19年  2月15日在9:17
添加评论
0
使用openssh_keypair和authorized_key模块可以同时创建和部署密钥，而无需将其保存到您的ansible主机中。
- openssh_keypair:
    group: root
    owner: root
    path: /some/path/in/your/server
    register: ssh_key
- name: Store public key into origin
  delegate_to: central_server_name
  authorized_key:
     key: "{{ssh_key.public_key}}"
     comment: "{{ansible_hostname}}"
     user: any_user_on_central
